<template>
  <div>
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>用户管理</span>
      </div>
      <el-form :inline="true" :model="searchForm" class="demo-form-inline">
        <el-form-item label="用户名称：">
          <el-input v-model="searchForm.realName" placeholder="请输入用户名称" clearable size="small"></el-input>
        </el-form-item>
        <el-form-item label="手机号：">
          <el-input v-model="searchForm.phonenumber" placeholder="请输入手机号" clearable size="small"></el-input>
        </el-form-item>
        <el-form-item label="状态：">
          <el-select v-model="searchForm.status" placeholder="请选择用户状态" clearable size="small">
            <el-option label="正常" value="0"></el-option>
            <el-option label="停用" value="1"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="创建时间：">
          <el-date-picker
            v-model="dateRange"
            size="small"
            type="daterange"
            range-separator="-"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd">
          </el-date-picker>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="doSearch">搜索</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card class="box-card">
      <el-button type="primary" style="margin-bottom: 10px" @click="handleAdd" v-hasPermi="'system:user:add'">添加</el-button>
      <el-button type="primary" style="margin-bottom: 10px" @click="handleExport">导出</el-button>
      <el-upload
          style="display:inline; margin-left: 10px;"
          action="/api/sys/user/import"
          :headers="{'Authorization':'Bearer '+$store.state.token}"
          :show-file-list="false"
          :before-upload="beforeUpload"
          :on-success="onSuccess"
          :on-error="onError">
        <el-button type="primary" style="margin-bottom: 10px;margin-bottom:30px" :loading="isLoading">导入</el-button>
      </el-upload>
      <el-table :data="pageData.data" style="width: 100%" border>
        <el-table-column prop="userId" label="编号" width="80px"></el-table-column>
        <el-table-column prop="realName" label="用户名称"></el-table-column>
        <el-table-column prop="userName" label="账号"></el-table-column>
        <el-table-column prop="dept.deptName" label="部门"></el-table-column>
        <el-table-column prop="phonenumber" label="手机号"></el-table-column>
        <el-table-column prop="status" label="状态" width="80px">
          <template slot-scope="scope">
             {{scope.row.status==1?"停用":"正常"}}
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间"></el-table-column>
        <el-table-column label="操作"  width="240px">
          <template slot-scope="scope">
            <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">
              编辑
            </el-button>
            <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">
              删除
            </el-button>
            <el-button type="success" size="mini" @click="handleUpdatePwd(scope.$index, scope.row)">
              重置密码
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="pageData.pageNo"
        :page-sizes="[5, 10, 15, 20]"
        :page-size="pageData.pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="pageData.totalCount">
      </el-pagination>

      <el-dialog :title="saveForm.userId==null?'新增用户':'修改用户'" :visible.sync="dialogFormVisible">
        <el-form :model="saveForm" :rules="rules" ref="saveForm" :inline="true" label-width="90px">
          <el-form-item label="用户昵称" prop="realName">
            <el-input v-model="saveForm.realName" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="归属部门">
            <treeselect 
              v-model="saveForm.deptId"
              :normalizer="normalizeOptions"
              placeholder="请选择归属部门" 
              :options="deptOptions"
              style="width:205px">
            </treeselect>
          </el-form-item>
          <el-form-item label="手机号码" prop="phonenumber">
            <el-input v-model="saveForm.phonenumber" autocomplete="off" maxlength="11"></el-input>
          </el-form-item>
          <el-form-item label="邮箱" prop="email">
            <el-input v-model="saveForm.email" autocomplete="off" maxlength="50"></el-input>
          </el-form-item>
          <el-form-item label="用户名称" prop="userName" v-if="!saveForm.userId">
            <el-input v-model="saveForm.userName" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="用户密码" prop="password" v-if="!saveForm.userId">
            <el-input v-model="saveForm.password" autocomplete="off" type="password"></el-input>
          </el-form-item>
          <el-form-item label="用户性别">
            <el-select v-model="saveForm.sex" style="width:205px">
              <el-option label="男" value="0"></el-option>
              <el-option label="女" value="1"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="状态">
            <el-radio-group v-model="saveForm.status">
              <el-radio label="0">正常</el-radio>
              <el-radio label="1">停用</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="岗位">
            <el-select v-model="saveForm.postIds" placeholder="请选择岗位" multiple style="width:205px">
              <el-option
                v-for="item in postOptions"
                :key="item.postId"
                :label="item.postName"
                :value="item.postId"
                :disabled="item.status == 1"/>
            </el-select>
          </el-form-item>
          <el-form-item label="角色">
            <el-select v-model="saveForm.roleIds" multiple placeholder="请选择">
              <el-option
                v-for="item in roleOptions"
                :key="item.roleId"
                :label="item.roleName"
                :value="item.roleId"
                :disabled="item.status == 1"/>
            </el-select>
          </el-form-item>
          <el-form-item label="备注" >
            <el-input type="textarea" v-model="saveForm.remark" autocomplete="off" style="width:520px"></el-input>
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取 消</el-button>
          <el-button type="primary" @click="doSave">确 定</el-button>
        </div>
      </el-dialog>
    </el-card>
  </div>
</template>

<script>
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
export default {
  components: {
    Treeselect
  },
  data() {
    return {
      //显示是否加载中
      isLoading:false,
      dateRange:[],
      //查询的数据模型
      searchForm: {
        //过滤条件
        realName: null,
        phonenumber: null,
        status: null,
        beginTime: null,
        endTime: null,
        
        //分页条件
        pageNo: 1,
        pageSize: 5,
      },
      //部门树下拉框
      deptOptions:[],
      //角色下拉框
      roleOptions:[],
      //岗位下拉框
      postOptions:[],
      //分页数据模型
      pageData: {
        data: [], // 分页数据
        pageNo: 1, // 当前页
        pageSize: 5, // 一页的大小
        totalCount: 0, // 总数据量
        totalPageCount: 0, // 总页数
      },
      //控制对话框显示还是隐藏
      dialogFormVisible: false,
      //新增的数据模型
      saveForm: {
        userId:null,
        realName:null,
        deptId:null,
        phonenumber:null,
        email:null,
        userName:null,
        password:"123456",
        sex:null,
        status:"0",
        remark: null,
        roleIds:[],
        postIds:[],
      },
      //验证数据模型
      rules: {
        realName: [
          { required: true, message: "请输入真实姓名！", trigger: "blur" },
        ],
        userName: [
          { required: true, message: "请输入真实姓名！", trigger: "blur" },
        ],
        password: [
          { required: true, message: "请输入电话号码！", trigger: "blur" },
        ],
        email: [
          {
            type: 'email',
            message: '\'请输入正确的邮箱地址',
            trigger: ['blur', 'change']
          }
        ],
        phonenumber: [
          {
            pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
            message: '请输入正确的手机号码',
            required: true,
            trigger: 'blur'
          }
        ]
      },
    };
  },
  created() {
    this.doSearch();
    this.doTreeSelect();
    this.doRoleOptionselect();
    this.doPostOptionselect();
  },
  methods: {
    //查询用户信息
    doSearch() {
      //获取开始时间和结束时间
      if (this.dateRange) {
        this.searchForm.beginTime = this.dateRange[0]
        this.searchForm.endTime = this.dateRange[1]
      }else{
        this.searchForm.beginTime =null;
        this.searchForm.endTime =null;
      }
      this.$axios.get("/api/sys/user/list", {params:this.searchForm})
        .then((res) => {
          if (res.data.code == 200) {
            this.pageData.pageNo = res.data.data.current;
            this.pageData.pageSize = res.data.data.size;
            this.pageData.totalCount = res.data.data.total;
            this.pageData.totalPageCount = res.data.data.pages;
            this.pageData.data = res.data.data.records;
          } else {
            this.$message.error(res.data.msg);
          }
        })
        .catch((err) => {
          console.log(err);
        });
    },
    //查询部门树
    doTreeSelect() {
      this.$axios.get("/api/sys/dept/treeselect")
        .then((res) => {
          if (res.data.code == 200) {
            this.deptOptions = res.data.data;
          } else {
            this.$message.error(res.data.msg);
          }
        })
        .catch((err) => {
          console.log(err);
        });
    },
    //查询角色下拉
    doRoleOptionselect() {
      this.$axios.get("/api/sys/role/optionselect")
        .then((res) => {
          if (res.data.code == 200) {
            this.roleOptions = res.data.data;
          } else {
            this.$message.error(res.data.msg);
          }
        })
        .catch((err) => {
          console.log(err);
        });
    },
    //查询岗位下拉
    doPostOptionselect() {
      this.$axios.get("/api/sys/post/optionselect")
        .then((res) => {
          if (res.data.code == 200) {
            this.postOptions = res.data.data;
          } else {
            this.$message.error(res.data.msg);
          }
        })
        .catch((err) => {
          console.log(err);
        });
    },
    //改变每页显示的条数
    handleSizeChange(val) {
      this.searchForm.pageSize = val;
      this.doSearch();
    },
    //改变当前的页码数
    handleCurrentChange(val) {
      this.searchForm.pageNo = val;
      this.doSearch();
    },
    //清空新增表单数据
    reset () {
      this.saveForm = {
        userId:null,
        realName:null,
        deptId:null,
        phonenumber:null,
        email:null,
        userName:null,
        password:"123456",
        sex:null,
        status:"0",
        remark: null,
        roleIds:[],
        postIds:[],
      };
    },
    //添加
    handleAdd() {
      //1.清空模型数据
      this.reset();
      //2.显示对话框
      this.dialogFormVisible = true;
    },
    //保存
    doSave() {
      this.$refs["saveForm"].validate((vali) => {
        if (vali) {
          //发送ajax请求
          this.$axios.post("/api/sys/user/save", this.saveForm)
            .then((res) => {
              if (res.data.code == 200) {
                //1.关闭对话框
                this.dialogFormVisible = false;
                //2.友好提示
                this.$message.success(res.data.msg);
                //3.刷新表格
                this.doSearch();
              } else {
                //1.友好提示
                this.$message.error(res.data.msg);
              }
            })
            .catch((err) => {
              console.log(err);
            });
        }
      });
    },
    //编辑
    handleEdit(index, row) {
      //1.清空模型数据
      this.reset();
      //2.查询要修改的数据
      this.$axios.get("/api/sys/user/view/"+row.userId).then((res)=>{
         if(res.data.code==200){   
            this.saveForm=res.data.data;
         }else{
            this.$message.error(res.data.msg);
         }
      }).catch((err)=>{
        console.log(err);
      })
      //3.显示对话框
      this.dialogFormVisible=true;
    },
    //删除
    handleDelete(index, row) {
        this.$confirm('确定要删除吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          //1.发送ajax请求
          this.$axios.delete("/api/sys/user/del/"+row.userId).then((res)=>{
              if (res.data.code == 200) {
                //1.友好提示
                this.$message.success(res.data.msg);
                //2.刷新表格
                this.doSearch();
              } else {
                //1.友好提示
                this.$message.error(res.data.msg);
              }
          }).catch((err)=>{
              console.log(err);
          })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });          
        });
    },
    // 转换部门数据结构
    normalizeOptions(node) {
      if (node.children && !node.children.length) {
        // 去掉children=[]的children属性
        delete node.children;
      }
      return {
        id: node.deptId,
        label: node.deptName,
        children: node.children,
      };
    },
    //修改密码
    handleUpdatePwd(index, row) {
      this.$prompt('请输入'+row.realName+'的新密码', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        // inputPattern: /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/,
        inputErrorMessage: '密码格式不正确'
      }).then(({ value }) => {
        //1.发送ajax请求
        this.$axios.put("/api/sys/user/resetPwd",{userId:row.userId,password:value}).then((res)=>{
          if (res.data.code == 200) {
            //1.友好提示
            this.$message.success(res.data.msg);
          } else {
            //1.友好提示
            this.$message.error(res.data.msg);
          }
        }).catch((err)=>{
          console.log(err);
        })
      }).catch(()=>{
        this.$message({
          type: 'info',
          message: '取消输入'
        }); 
      });
    },
    //导出
    handleExport(){
      this.$axios.get("/api/sys/user/export",
          {
            params:this.searchForm,
            responseType:"blob" //指定响应的类型
          }).then((res)=>{
        let blob=new Blob([res.data], {
          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        });
        let url=window.URL.createObjectURL(blob);
        let a = document.createElement('a')
        a.href = url

        const contentDisposition = res.headers['content-disposition']
        let fileName = 'xxx.xlsx'
        if (contentDisposition) {
          // 解析响应头中的文件名（后端需设置正确的header）
          const match = contentDisposition.match(/filename=(.+)/)
          if (match && match[1]) {
            fileName = decodeURIComponent(match[1])
          }
        }
        // 指定下载后的文件名
        a.download = fileName
        //test

        document.body.appendChild(a)
        a.click()
        window.URL.revokeObjectURL(url)
        document.body.removeChild(a)

        this.$message.success("导出成功");
      }).catch((err)=>{
        this.$message.error("导出失败");
        console.log(err);
      })
    },
    //上传前
    beforeUpload(){
      this.isLoading=true;
    },
    //上传成功
    onSuccess(){
      this.isLoading=false;
      this.$message.success("导入成功");
      this.doSearch();
    },
    //上传失败
    onError(){
      this.isLoading=false;
    }
  },
}
</script>

<style scoped>
</style>

